package com.arrogames.blondbattle.game.rendering
{
	import ash.core.Engine;
	import ash.core.NodeList;
	import ash.core.System;
	
	import com.arrogames.blondbattle.game.EntityCreator;
	import com.arrogames.blondbattle.game.graphics.animation.Destroyable;
	import com.arrogames.blondbattle.game.rendering.Display;
	import com.arrogames.blondbattle.game.movement.Position;
	import com.arrogames.blondbattle.game.rendering.RenderNode;
	
	import starling.display.DisplayObject;
	import starling.display.DisplayObjectContainer;

	import org.as3commons.logging.api.getLogger;
	import org.as3commons.logging.api.ILogger;
	
	public class RenderSystem extends System
	{
	
		private static const logger:ILogger = getLogger(RenderSystem);
	
		public var container : DisplayObjectContainer;
		
		private var nodes : NodeList;
		private var creator:EntityCreator;
		
		public function RenderSystem( container : DisplayObjectContainer, entityCreator:EntityCreator )
		{
			this.container = container;
			this.creator = entityCreator;
		}
		
		override public function addToEngine( engine : Engine ) : void
		{
			nodes = engine.getNodeList( RenderNode );
			for( var node : RenderNode = nodes.head; node; node = node.next )
			{
				addToDisplay( node );
			}
			nodes.nodeAdded.add( addToDisplay );
			nodes.nodeRemoved.add( removeFromDisplay );
		}
		
		private function addToDisplay( node : RenderNode ) : void
		{
			container.addChild( node.display.displayObject );
		}
		
		private function removeFromDisplay( node : RenderNode ) : void
		{
			container.removeChild( node.display.displayObject );
		}
		
		override public function update( time : Number ) : void
		{
			var node : RenderNode;
			var position : Position;
			var display : Display;
			var displayObject : DisplayObject;
			
			for( node = nodes.head; node; node = node.next )
			{
				display = node.display;
				displayObject = display.displayObject;
				if ( displayObject is Destroyable ) {
					checkDestroyable(node, displayObject as Destroyable);
				}
				
				position = node.position;
				
				displayObject.x = position.position.x;
				displayObject.y = position.position.y;
				displayObject.rotation = position.rotation;
			}
		}

		override public function removeFromEngine( engine : Engine ) : void
		{
			nodes = null;
		}
		
		/**
		 * Check for the destroyable to see if can be destroyed yet
		 * 
		 * @param	node		RenderNode
		 * @param	destroyable	the displayobject implementing Destroyable
		 */
		private function checkDestroyable(node:RenderNode, destroyable:Destroyable) : void
		{
			//check if the animation has ended, if so we can safely remove the object
			if (destroyable.getAnimationEnded() ) {
				//remove the destroyable from the game
				logger.debug("removing destroyable: " + node.entity.name);
				creator.destroyEntity(node.entity);
			}
		}
	}
}
